#include "ollamaapi.h"
#include <QNetworkRequest>
#include <QUrl>
#include <QDebug>

// OllamaAPI类构造函数
OllamaAPI::OllamaAPI(QObject *parent) : QObject(parent),
    m_currentReply(nullptr)  // 初始化当前回复指针为空
{
    // 创建网络访问管理器
    m_manager = new QNetworkAccessManager(this);
    // 连接网络请求完成信号到处理槽函数
    connect(m_manager, &QNetworkAccessManager::finished, 
            this, &OllamaAPI::onReplyFinished);
    // 设置Ollama API默认基础URL（本地默认端口）
    m_baseUrl = "http://localhost:11434";
}

// 设置API基础URL
void OllamaAPI::setBaseUrl(const QString &url) {
    m_baseUrl = url;
}

// 中止当前请求
void OllamaAPI::abortCurrentRequest() {
    if (m_currentReply) {
        m_currentReply->abort();  // 中止请求
        m_currentReply->deleteLater();  // 延迟删除
        m_currentReply = nullptr;  // 重置指针
    }
}

// 发送消息到Ollama API
void OllamaAPI::sendMessage(const QString &model, const QString &message) {
    abortCurrentRequest();  // 先中止任何现有请求
    
    // 构建API请求URL
    QUrl url(m_baseUrl + "/api/chat");
    QNetworkRequest request(url);
    // 设置请求头
    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
    request.setRawHeader("Accept", "application/json");
    
    // 构建JSON请求体
    QJsonObject json;
    json["model"] = model;  // 设置要使用的模型
    
    // 构建消息数组
    QJsonArray messagesArray;
    QJsonObject messageObject;
    messageObject["role"] = "user";  // 消息角色为用户
    messageObject["content"] = message;  // 消息内容
    messagesArray.append(messageObject);
    
    // 添加消息数组到请求体
    json["messages"] = messagesArray;
    json["stream"] = true;  // 启用流式响应
    
    // 将JSON转换为字节数组
    QByteArray postData = QJsonDocument(json).toJson();
    
    // 发送POST请求
    m_currentReply = m_manager->post(request, postData);
    // 连接数据就绪信号，用于处理流式数据
    connect(m_currentReply, &QNetworkReply::readyRead, 
            this, &OllamaAPI::onReadyRead);
    m_buffer.clear();  // 清空缓冲区
}

// 处理接收到的流式数据
void OllamaAPI::onReadyRead()
{
    if (!m_currentReply) return;  // 安全检查

    // 逐行处理响应数据
    while (m_currentReply->canReadLine()) {
        QByteArray line = m_currentReply->readLine().trimmed();
        // 跳过空行或结束标记
        if (line.isEmpty() || line == "data: [DONE]") continue;

        // 移除SSE格式的"data: "前缀
        if (line.startsWith("data: ")) {
            line = line.mid(6);
        }

        // 解析JSON数据
        QJsonParseError error;
        QJsonDocument doc = QJsonDocument::fromJson(line, &error);
        
        if (error.error != QJsonParseError::NoError) {
            qDebug() << "JSON解析错误:" << error.errorString() << "所在行:" << line;
            continue;
        }

        // 从响应中提取内容
        QJsonObject obj = doc.object();
        if (!obj.isEmpty() && obj.contains("message")) {
            QJsonObject messageObj = obj["message"].toObject();
            if (messageObj.contains("content")) {
                QString content = messageObj["content"].toString();
                emit responseStream(content);  // 发射信号传递内容
            }
        }
    }
}

// 处理网络请求完成
void OllamaAPI::onReplyFinished(QNetworkReply *reply) {
    // 如果不是当前回复则忽略
    if (reply != m_currentReply) {
        reply->deleteLater();
        return;
    }
    
    // 如果没有错误且缓冲区有数据，处理剩余数据
    if (reply->error() == QNetworkReply::NoError && !m_buffer.isEmpty()) {
        QJsonDocument doc = QJsonDocument::fromJson(m_buffer.toUtf8());
        if (!doc.isNull()) {
            QJsonObject obj = doc.object();
            if (obj.contains("message")) {
                QJsonObject messageObj = obj["message"].toObject();
                if (messageObj.contains("content")) {
                    emit responseStream(messageObj["content"].toString());
                }
            }
        }
    }
    
    // 如果发生错误（且不是取消操作），发射错误信号
    if (reply->error() != QNetworkReply::NoError && 
        reply->error() != QNetworkReply::OperationCanceledError) {
        emit errorOccurred(reply->errorString());
    }
    
    // 发射请求完成信号
    emit responseFinished();
    m_currentReply = nullptr;  // 重置当前回复
    reply->deleteLater();  // 延迟删除回复对象
}
